package logic.common.player.awards;

import java.util.HashMap;

import fileHandling.SettingsLoader;
import fileHandling.language.interfaces.AwardType;

import networking.messages.syncMessages.ValueType;

import logic.common.missions.ConquerMission;
import logic.common.missions.DroneHarassMission;
import logic.common.missions.Mission;
import logic.common.player.Player;
import logic.common.player.playerListeners.HunterChangedEvent;
import logic.common.player.playerListeners.KillAssistEvent;
import logic.common.player.playerListeners.KillEvent;
import logic.common.player.playerListeners.MissionAssistEvent;
import logic.common.player.playerListeners.PlayerListener;
import logic.common.player.playerListeners.PlayerTeamListener;
import logic.common.player.playerListeners.PlayerValueListener;
import logic.common.player.playerListeners.RespawnEvent;
import logic.common.player.playerListeners.TargetChangedEvent;
import logic.common.team.Team;
import logic.common.team.teamListeners.MissionAddedEvent;
import logic.common.team.teamListeners.MissionCompletedEvent;
import logic.common.team.teamListeners.MissionDeletedEvent;
import logic.common.team.teamListeners.TeamMissionListener;
import logic.nodes.nodeSettings.Settings;
import logic.status.StatusChangedEvent;
import logic.weapons.WeaponType;

public class AwardManager {
	
	public static final String AWARDS_FILE = "data/ui/awards.xml";
	
	private static Settings awardSettings;
	
	private Player player;
	private int missionAssists, killAssists, killStreak, stationCaptures, droneKills;
	private HashMap<WeaponType, Integer> weaponKillMap;
	
	public AwardManager(Player player) {
		this.player = player;
		
		weaponKillMap = new HashMap<WeaponType, Integer>();
		Integer zero = Integer.valueOf(0);
		weaponKillMap.put(WeaponType.Energy, zero);
		weaponKillMap.put(WeaponType.HeatSeeker, zero);
		weaponKillMap.put(WeaponType.Missile, zero);
		
		initListeners();
		
		checkAwardSettings();
	}
	
	private static void checkAwardSettings() {
		if(awardSettings == null) {
			awardSettings = SettingsLoader.loadSettings(AWARDS_FILE);
		}
	}
	
	private void initListeners() {
		player.addPlayerListener(new PlayerListener() {
			@Override
			public void missionAssist(MissionAssistEvent event) {
				missionAssists++;
				if(missionAssists == 5) {
					player.addAward(createAward(player, AwardType.Five_Mission_Assists));
					missionAssists = 0;
				}
			}
			
			@Override
			public void killed(KillEvent event) {
				killStreak++;
				if(killStreak == 3) {
					player.addAward(createAward(player, AwardType.Three_Kill_Streak));
				} else if(killStreak == 5) {
					player.addAward(createAward(player, AwardType.Five_Kill_Streak));
				}
				
				WeaponType weaponType = event.getWeapon().getWeaponType();
				Integer value = weaponKillMap.get(weaponType);
				int newValue = value.intValue() + 1;
				
				if(newValue == 5) {
					AwardType type = null;
					switch(weaponType) {
						case Energy: type = AwardType.Five_Energy_Kills; break;
						case HeatSeeker: type = AwardType.Five_Heatseeker_Kills; break;
						case Missile: type = AwardType.Five_Missile_Kills; break;
					}
					
					assert(type != null);
					player.addAward(createAward(player, type));
					newValue = 0;
				}
				
				weaponKillMap.put(weaponType, Integer.valueOf(newValue));
			}
			
			@Override
			public void killAssist(KillAssistEvent event) {
				killAssists++;
				if(killAssists == 8) {
					player.addAward(createAward(player, AwardType.Eight_Kill_Assists));
					killAssists = 0;
				}
			}
			
			@Override
			public void hunterChanged(HunterChangedEvent event) {}
			@Override
			public void targetChanged(TargetChangedEvent event) {}
			@Override
			public void respawned(RespawnEvent event) {}
		});
		
		player.addPlayerValueListener(new PlayerValueListener() {
			@Override
			public void valueChanged(StatusChangedEvent event) {
				if(event.getType() == ValueType.Deaths) killStreak = 0;
			}
		});
		
		player.getTeam().addMissionListener(new TeamMissionListener() {
			@Override
			public void missionCompleted(MissionCompletedEvent event) {
				if(event.getPlayer() == player) {
					
					Mission mission = event.getMission();
					if(mission instanceof DroneHarassMission) {
						droneKills++;
						if(droneKills == 8) {
							player.addAward(createAward(player, AwardType.Eight_Drone_Kills));
							droneKills = 0;
						}
					} else if(mission instanceof ConquerMission) {
						stationCaptures++;
						if(stationCaptures == 3) {
							player.addAward(createAward(player, AwardType.Three_Station_Captures));
							stationCaptures = 0;
						}
					}
				}
			}

			@Override
			public void missionDeleted(MissionDeletedEvent event) {}
			@Override
			public void missionAdded(MissionAddedEvent event) {}
		});
		
		player.addPlayerTeamListener(new PlayerTeamListener() {
			@Override
			public void teamChanged(Team newTeam) {
				killStreak = 0;
			}
			
			@Override
			public void teamChangeFailed() {}
		});
	}
	
	public static Award createAward(Player player, AwardType type) {
		checkAwardSettings();
		int money = Integer.valueOf(awardSettings.getValueOf(type)).intValue();
		return new Award(player, type, money);
	}
}